From: Matthias Clasen Date: Tue, 23 May 2023 17:49:04 +0000 (-0400) Subject: listitemmanager: Listen to sections-changed X-Git-Tag: archive/raspbian/4.12.3+ds-1+rpi1~1^2^2^2~59^2^2~215^2 X-Git-Url: https://dgit.raspbian.org/%22http://www.example.com/cgi/%22/%22http:/www.example.com/cgi/%22?a=commitdiff_plain;h=215f60e450e7f09ddea002f25ae29f3888921041;p=gtk4.git listitemmanager: Listen to sections-changed And recreate header and footer tiles as needed. This commit was tested using a sortlistmodel, changing the section sorter from sorting only by first char to sorting by the first two chars, which changes the number of sections, but leaves the alphabetic order of items unchanged. --- diff --git a/gtk/gtklistitemmanager.c b/gtk/gtklistitemmanager.c index aa5c9b1bf8..3c63c70ac3 100644 --- a/gtk/gtklistitemmanager.c +++ b/gtk/gtklistitemmanager.c @@ -1565,6 +1565,67 @@ gtk_list_item_manager_model_items_changed_cb (GListModel *model, gtk_widget_queue_resize (self->widget); } +static void +gtk_list_item_manager_model_sections_changed_cb (GListModel *model, + guint position, + guint n_items, + GtkListItemManager *self) +{ + GtkListItemChange change; + GtkListTile *tile, *header; + guint offset; + + if (!gtk_list_item_manager_has_sections (self)) + return; + + gtk_list_item_change_init (&change); + + tile = gtk_list_item_manager_get_nth (self, position, &offset); + header = gtk_list_tile_get_header (self, tile); + gtk_list_item_change_clear_header (&change, &header->widget); + gtk_list_tile_set_type (header, GTK_LIST_TILE_UNMATCHED_HEADER); + + n_items -= MIN (n_items, position - offset); + while (n_items > 0) + { + switch (tile->type) + { + case GTK_LIST_TILE_HEADER: + case GTK_LIST_TILE_UNMATCHED_HEADER: + gtk_list_item_change_clear_header (&change, &tile->widget); + gtk_list_tile_set_type (tile, GTK_LIST_TILE_REMOVED); + break; + + case GTK_LIST_TILE_FOOTER: + case GTK_LIST_TILE_UNMATCHED_FOOTER: + gtk_list_tile_set_type (tile, GTK_LIST_TILE_REMOVED); + break; + + case GTK_LIST_TILE_ITEM: + n_items -= MIN (n_items, tile->n_items); + break; + + case GTK_LIST_TILE_REMOVED: + default: + g_assert_not_reached (); + break; + } + + tile = gtk_list_tile_get_next_skip (tile); + } + + if (!gtk_list_tile_is_footer (tile)) + tile = gtk_list_tile_get_footer (self, tile); + + gtk_list_tile_set_type (tile, GTK_LIST_TILE_UNMATCHED_FOOTER); + + gtk_list_item_manager_ensure_items (self, &change, G_MAXUINT, 0); + + gtk_list_item_change_finish (&change); + + gtk_widget_queue_resize (GTK_WIDGET (self->widget)); +} + static void gtk_list_item_manager_model_selection_changed_cb (GListModel *model, guint position, @@ -1624,6 +1685,9 @@ gtk_list_item_manager_clear_model (GtkListItemManager *self) g_signal_handlers_disconnect_by_func (self->model, gtk_list_item_manager_model_items_changed_cb, self); + g_signal_handlers_disconnect_by_func (self->model, + gtk_list_item_manager_model_sections_changed_cb, + self); g_clear_object (&self->model); gtk_list_item_manager_gc_tiles (self); @@ -1682,6 +1746,11 @@ gtk_list_item_manager_set_model (GtkListItemManager *self, "selection-changed", G_CALLBACK (gtk_list_item_manager_model_selection_changed_cb), self); + if (GTK_IS_SECTION_MODEL (model)) + g_signal_connect (model, + "sections-changed", + G_CALLBACK (gtk_list_item_manager_model_sections_changed_cb), + self); gtk_list_item_change_init (&change); gtk_list_item_manager_add_items (self, &change, 0, g_list_model_get_n_items (G_LIST_MODEL (model)));